<template>
  <div class="init-container">
    <div class="mask-container" v-if="isMask"></div>
    <div class="none-container" v-if="nonePermission">
      {{ $srv.getI18nByPath('others.noPermissions') }}···
    </div>
    <div class="gain-key-container">
      <!-- 上部行车设置 -->
      <Row :gutter="16" class="top-section">
        <Col span="12">
          <Row>
            <Col span="12">
              <CraneParams
                title="一号行车"
                :params="craneParams.find(item => item.id === 1)"
                @param-update="handleParamUpdate"
              />
            </Col>
            <Col span="12">
              <CraneControl
                title="一号行车"
                :status="crane1Status"
                :craneControls="crane1Controls"
                :craneStates="cranehookStates[0]"
                @hook-change="handleCraneControl"
              />
            </Col>
          </Row>
        </Col>
        <Col span="12">
          <Row>
            <Col span="12">
              <CraneParams
                title="二号行车"
                :params="craneParams.find(item => item.id === 2)"
                @param-update="handleParamUpdate"
              />
            </Col>
            <Col span="12">
              <CraneControl
                title="二号行车"
                :craneControls="crane2Controls"
                :status="crane2Status"
                :craneStates="cranehookStates[1]"
                @hook-change="handleCraneControl"
              />
            </Col>
          </Row>
        </Col>
      </Row>

      <!-- 中部倾斜设置 -->
      <TiltSettings
        class="middle-section y-scroll"
        :class="{ 'admin-height': showAdvancedSettings }"
        :craneParams="tiltSettings"
        @setting-update="handleSettingUpdate"
      />

      <!-- 下部高级设置 -->
      <!-- v-if="showAdvancedSettings" -->
      <AdvancedSettings
        v-if="showAdvancedSettings"
        :isAdmin="showAdvancedSettings"
        class="bottom-section"
        :params="advancedSettings"
        @advanced-change="handleAdvancedUpdate"
        @priority-change="handlePriorityChange"
        @operation-change="handleOperationChange"
      />
    </div>
  </div>
</template>

<script lang="ts">
import {
  Tsrv,
  T_srv,
  ifs,
  ts,
  vue,
  I_cmd,
  T_cmd,
  N_drivingSet,
  craneParams,
  crane1Controls,
  crane2Controls,
  cranehookStates,
  tiltSettings,
  advancedSettings
} from './config';
import CraneParams from './CraneParams.vue';
import CraneControl from './CraneControl.vue';
import TiltSettings from './TiltSettings.vue';
import AdvancedSettings from './AdvancedSettings.vue';

@T_srv.comp({
  components: { CraneParams, CraneControl, TiltSettings, AdvancedSettings }
})
export default class cDrivingSet extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.prop({
    type: Object,
    default: () => {}
  })
  config!: any;

  /* 组件名 */
  private name: string = 'cDrivingSet';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  /* 遮罩 */
  public isMask: boolean = false;

  private nonePermission: boolean = false;

  // 行车参数
  private craneParams: N_drivingSet.craneParams[] = craneParams();

  // 行车控制
  private crane1Controls: N_drivingSet.ControlState[] = crane1Controls();

  private crane2Controls: N_drivingSet.ControlState[] = crane2Controls();

  // 行车甲乙钩控制
  private cranehookStates: N_drivingSet.HookState[][] = cranehookStates();

  private codes: string[] = [];

  // 行车状态
  private crane1Status = {
    isPaused: false,
    errInfo: [
      {
        code: '',
        msg: '',
        active: false
      }
    ]
  };

  private crane2Status = {
    isPaused: false,
    hooksActive: [false, true]
  };

  // 倾斜设置
  private tiltSettings: N_drivingSet.TiltParams[] = tiltSettings();

  // 高级设置
  private advancedSettings: N_drivingSet.AdvancedSettings = advancedSettings();

  get showAdvancedSettings(): boolean {
    // 权限判断逻辑
    return Tsrv.store.getters.SysInfo.roleInfo[0].roleType === 1;
  }

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.init();
    this.GT_command.startTask();
  }

  private receiveEvent() {
    this.$bus.$on(
      '__PLC_CONNSTATE__',
      (data: { connState: boolean; ecBoxName: string }) => {
        if (data.ecBoxName === 'mianyang') {
          if (data.connState) {
            if (!this.GT_command.isOpenTask) {
              this.GT_command.startTask();
            }
          } else {
            this.GT_command.stopTask();
          }
        }
      }
    );
  }

  destroyed() {
    this.GT_command.stopTask();
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);
    this.$bus.$off('__PLC_CONNSTATE__');

    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  private init() {
    // 功能“浏览”权限
    const defaultPermission = Tsrv.utils.find(
      this.config.permission,
      item => item.area === 'default'
    );
    this.nonePermission = !defaultPermission?.data?.browse;
    if (this.nonePermission) return;

    this.codes = [];
    for (const crane of this.craneParams) {
      Object.keys(crane).forEach(key => {
        if (!Tsrv.noValue(crane[key].code)) {
          this.codes.push(crane[key].code);
        }
      });
    }

    for (const crane of this.cranehookStates) {
      for (const hooke of crane) {
        this.codes.push(hooke.code);
      }
    }

    for (const tilt of this.tiltSettings) {
      Object.keys(tilt).forEach(key => {
        if (key !== 'id') {
          Object.keys(tilt[key]).forEach(k => {
            this.codes.push(tilt[key][k].code);
          });
        }
      });
    }
    // 注释部分目前点位没有导入系统，误删
    this.advancedSettings.priority.crane1.data.forEach(row => {
      Object.keys(row).forEach(key => {
        this.codes.push(row[key].code);
      });
    });

    this.advancedSettings.priority.crane2.data.forEach(row => {
      Object.keys(row).forEach(key => {
        this.codes.push(row[key].code);
      });
    });

    Object.keys(this.advancedSettings.operation).forEach(key => {
      this.codes.push(this.advancedSettings.operation[key].code);
    });

    Object.keys(this.advancedSettings.advanced).forEach(key1 => {
      Object.keys(this.advancedSettings.advanced[key1]).forEach(key2 => {
        this.codes.push(this.advancedSettings.advanced[key1][key2].code);
      });
    });

    this.updateData();
  }

  public updateData() {
    Tsrv.readPlcData(this.codes).then(res => {
      if (typeof res !== 'boolean') {
        for (const crane of this.craneParams) {
          Object.keys(crane).forEach(key => {
            if (!Tsrv.noValue(crane[key].code)) {
              // this.setParamValue(crane[key], res[crane[key].code].v);
              crane[key].value = res[crane[key].code].v;
            }
          });
        }

        for (const crane of this.cranehookStates) {
          for (const hooke of crane) {
            // this.setParamValue(hooke, res[hooke.code]);
            hooke.active = res[hooke.code].v;
          }
        }

        for (const tilt of this.tiltSettings) {
          Object.keys(tilt).forEach(key => {
            if (key !== 'id') {
              Object.keys(tilt[key]).forEach(k => {
                tilt[key][k].value = res[tilt[key][k].code].v;
              });
              // this.setParamValue(tilt[key], res[tilt[key].code].v);
            }
          });
        }

        this.advancedSettings.priority.crane1.data.forEach(row => {
          Object.keys(row).forEach(key => {
            // this.setParamValue(row[key], res[row[key].code].v);
            row[key].value = res[row[key].code].v;
          });
        });

        this.advancedSettings.priority.crane2.data.forEach(row => {
          Object.keys(row).forEach(key => {
            // this.setParamValue(row[key], res[row[key].code].v);
            row[key].value = res[row[key].code].v;
          });
        });

        Object.keys(this.advancedSettings.operation).forEach(key => {
          // this.setParamValue(
          //   this.advancedSettings.operation[key],
          //   res[this.advancedSettings.operation[key].code].v
          // );
          this.advancedSettings.operation[key].value =
            res[this.advancedSettings.operation[key].code].v;
        });

        Object.keys(this.advancedSettings.advanced).forEach(key1 => {
          Object.keys(this.advancedSettings.advanced[key1]).forEach(key2 => {
            // this.setParamValue(
            //   this.advancedSettings.advanced[key1][key2],
            //   res[this.advancedSettings.advanced[key1][key2].code].v
            // );
            if (key2 === 'specialMaterialValid') {
              this.advancedSettings.advanced[key1][key2].value = !res[
                this.advancedSettings.advanced[key1][key2].code
              ].v;
            } else {
              this.advancedSettings.advanced[key1][key2].value =
                res[this.advancedSettings.advanced[key1][key2].code].v;
            }
          });
        });
      }
    });
  }

  private setParamValue(obj: N_drivingSet.setInfo, value: boolean | number) {
    obj.value = value;
  }

  /* 设置组件整体遮罩 */
  public setMask(p: boolean) {
    this.isMask = p;
  }

  public getMask(p: boolean): boolean {
    return this.isMask;
  }

  private handleParamUpdate(obj: {
    id: number;
    field: string;
    params: N_drivingSet.setInfo;
  }) {
    // PLC写入接口调用
    for (const crane of this.craneParams) {
      if (crane.id === obj.id) {
        // crane[obj.field].value = obj.params.value;
        const data = [
          {
            ecDetCode: crane[obj.field].code,
            value: obj.params.value.toString()
          }
        ];
        Tsrv.writePlcData(data).then(_ => {
          // this.$Message.success(`更新行车${obj.id}参数成功`);
          // 读取参数重新赋值
          Tsrv.readPlcData([crane[obj.field].code]).then(res => {
            if (typeof res !== 'boolean') {
              crane[obj.field].value = res[crane[obj.field].code].v;
            }
          });
        });
        break;
      }
    }
  }

  private handleCraneControl(params: { title: string; type: string }) {
    const index = params.title === '一号行车' ? 0 : 1;

    for (const hooke of this.cranehookStates[index]) {
      if (hooke.type === params.type) {
        hooke.active = !hooke.active;
        const data = [
          { ecDetCode: hooke.code, value: hooke.active ? 'true' : 'false' }
        ];
        Tsrv.writePlcData(data).then(success => {
          if (success) {
            this.$Message.success(
              `${hooke.label} ${hooke.active ? '有效' : '无效'}`
            );
          }
        });
        break;
      }
    }
  }

  private handleSettingUpdate(obj: {
    craneId: number;
    type: string;
    field: string;
    value: number;
  }) {
    for (const param of this.tiltSettings) {
      if (param.id === obj.craneId) {
        const data = [
          {
            ecDetCode: param[obj.type][obj.field].code,
            value: obj.value.toString()
          }
        ];
        Tsrv.writePlcData(data).then(_ => {
          // this.$Message.success(`更新行车${obj.craneId}参数成功`);
          // 读取参数重新赋值
          Tsrv.readPlcData([param[obj.type][obj.field].code]).then(res => {
            if (typeof res !== 'boolean') {
              param[obj.type][obj.field].value =
                res[param[obj.type][obj.field].code].v;
            }
          });
        });
        break;
      }
    }
  }

  handleAdvancedUpdate(obj: {
    crane: string;
    field: string;
    code: string;
    value: number | boolean;
  }) {
    let value = '';
    if (obj.field === 'specialMaterialValid') {
      value = (!obj.value as boolean).toString();
    } else {
      value = obj.value.toString();
    }
    const data = [{ ecDetCode: obj.code, value: obj.value.toString() }];
    Tsrv.writePlcData(data).then(_ => {
      // this.$Message.success(`更新行车${obj.crane}参数成功`);
      // 读取参数重新赋值
      Tsrv.readPlcData([obj.code]).then(res => {
        if (typeof res !== 'boolean') {
          if (obj.field !== 'specialMaterialValid') {
            this.advancedSettings.advanced[obj.crane][obj.field].value =
              res[obj.code].v;
          } else {
            this.advancedSettings.advanced[obj.crane][obj.field].value = !res[
              obj.code
            ].v;
          }
        }
      });
    });
  }

  private handlePriorityChange(obj: {
    crane: number;
    row: number;
    i: number;
    code: string;
    value: number;
  }) {
    // this.advancedSettings[obj.crane].data[obj.row][`col${obj.i}`].value =
    //   obj.value;
    const data = [{ ecDetCode: obj.code, value: obj.value.toString() }];
    Tsrv.writePlcData(data).then(_ => {
      // this.$Message.success(`更新行车${obj.crane}参数成功`);
      // 读取参数重新赋值
      Tsrv.readPlcData([obj.code]).then(res => {
        if (typeof res !== 'boolean')
          this.advancedSettings[obj.crane].data[obj.row][`col${obj.i}`].value =
            res[obj.code].v;
      });
    });
  }

  private handleOperationChange(obj: {
    field: number;
    code: string;
    value: number;
  }) {
    const data = [{ ecDetCode: obj.code, value: obj.value.toString() }];
    Tsrv.writePlcData(data).then(_ => {
      // this.$Message.success(`更新行车${obj.craneId}参数成功`);
      // 读取参数重新赋值
      Tsrv.readPlcData([obj.code]).then(res => {
        if (typeof res !== 'boolean') {
          this.advancedSettings.operation[obj.field].value = res[obj.code].v;
        }
      });
    });
  }
}
</script>

<style lang="scss" scoped>
$border-color-base: #d9d9d9;
.gain-key-container {
  height: 100%;
  padding: 20px;
  background: #e3e8e7;

  .top-section {
    height: 27%;
    // margin-bottom: 16px;

    ::v-deep .ivu-col {
      border-right: 1px solid $border-color-base;
      &:last-child {
        border-right: none;
      }
    }
  }

  .middle-section {
    height: inherit;
    &.admin-height {
      height: 30%; // 管理员保持固定高度
    }
    margin: 16px 0;
    padding-top: 16px;
    border-top: 1px solid $border-color-base;
  }

  .bottom-section {
    height: 40%;
    padding-top: 16px;
    border-top: 1px solid $border-color-base;
  }
}
</style>
